﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using RaisingStudio.SmallProgram.Library;
using RaisingStudio.SmallProgram.Web.Silverlight.raisingstudio.smallprogram;
using System.Windows.Browser;
using System.Reflection;
using System.Diagnostics;
using System.Threading;
using System.IO;

namespace RaisingStudio.SmallProgram.Web.Silverlight
{
    public partial class MainPage : UserControl
    {
        private string ProgramId
        {
            get;
            set;
        }

        public MainPage(string programId)
        {
            InitializeComponent();

            this.ProgramId = programId;

            GraphicsWindow.Initialize();
            TextWindow.Initialize();
            this.windowHost.Children.Add(GraphicsWindow.Element);
            this.windowHost.Children.Add(TextWindow.Element);
            if (!string.IsNullOrEmpty(programId))
            {
                ServiceSoapClient serviceSoapClient = new ServiceSoapClient();
                serviceSoapClient.LoadProgramAssemblyCompleted += new EventHandler<LoadProgramAssemblyCompletedEventArgs>(serviceSoapClient_LoadProgramAssemblyCompleted);
                serviceSoapClient.LoadProgramAssemblyAsync(programId);
            }
            base.Loaded += delegate
            {
                HtmlPage.Plugin.Focus();
                base.Dispatcher.BeginInvoke(delegate
                {
                    GraphicsWindow._keyboardControl.Focus();
                });
            };
        }

        private void OnClickSmallProgram(object sender, RoutedEventArgs e)
        {
            HtmlPage.Window.Navigate(new Uri("http://smallprogram.codeplex.com/"), "_blank");
        }

        private void OnClickProgramDetails(object sender, RoutedEventArgs e)
        {
            HtmlPage.Window.Navigate(new Uri("http://5ifree.eicp.net:8000/apps/smallprogram/program?" + this.ProgramId), "_blank");
        }

        private Assembly compiledAssembly;
        private Thread programThread;
        private void RunProgram()
        {
            if (this.programThread != null)
            {
                this.programThread.Abort();
            }
            if (this.compiledAssembly != null)
            {
                ThreadStart threadStart = new ThreadStart(RunCompiledAssembly);
                this.programThread = new Thread(threadStart);
                this.programThread.Start();
            }
        }
        private void RunCompiledAssembly()
        {
            RunAssembly(this.compiledAssembly);
        }
        private void RunAssembly(Assembly compiledAssembly)
        {
            if (compiledAssembly != null)
            {
                foreach (var type in compiledAssembly.GetTypes())
                {
                    MethodInfo methodInfo = type.GetMethod("Main", BindingFlags.Public | BindingFlags.Static);
                    if (methodInfo != null)
                    {
                        methodInfo.Invoke(null, new object[] { });
                    }
                }
            }
        }

        private void OnRun(object sender, RoutedEventArgs e)
        {
            RunProgram();
        }

        void serviceSoapClient_LoadProgramAssemblyCompleted(object sender, LoadProgramAssemblyCompletedEventArgs e)
        {
            if ((!e.Cancelled) && (e.Error == null) && (e.Result != null))
            {
                AssemblyPart part = new AssemblyPart();
                MemoryStream stream = new MemoryStream(e.Result);
                var assembly = typeof(Primitive).Assembly;
                Debug.WriteLine(assembly);

                this.compiledAssembly = part.Load(stream);
                //stream.Dispose();
                RunProgram();
            }
            else
            {
                // TODO:
            }
        }
    }
}
